<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="./utils/reset.css" />
    <title>根据鼠标点击位置生成点</title>
  </head>
  <body>
    <canvas id="canvas"></canvas>

    <!-- 顶点着色器代码 -->
    <script type="shader-source" id="vertexShader">
      attribute vec4 point_Position;
      attribute float point_Size;
      void main(){
        // 定点位置
        gl_Position = point_Position;
        // 将要绘制点的大小
        gl_PointSize = point_Size;
      }
    </script>

    <!-- 片元着色器代码 -->
    <script type="shader-source" id="fragmentShader">
      precision mediump float;
      uniform vec4 point_Color;
      void main(){
          // 设置像素颜色
          gl_FragColor = point_Color;
      }
    </script>

    <script src="./utils/webgl-helper.js"></script>

    <script>
      const canvas = getCanvas("#canvas");
      resizeCanvas(canvas);

      const gl = getContext(canvas);

      // 创建顶点着色器
      const vertexShader = createShaderFromScript(
        gl,
        gl.VERTEX_SHADER,
        "vertexShader"
      );

      // 创建片元着色器
      const fragmentShader = createShaderFromScript(
        gl,
        gl.FRAGMENT_SHADER,
        "fragmentShader"
      );

      // 创建着色器程序
      const program = createSimpleProgram(gl, vertexShader, fragmentShader);

      const point_Position = gl.getAttribLocation(program, "point_Position");
      const point_Size = gl.getAttribLocation(program, "point_Size");
      const point_Color = gl.getUniformLocation(program, "point_Color");

      const points = [];

      canvas.addEventListener("click", ({ clientX, clientY }) => {
        // 获取鼠标点击位置相较于窗口位置
        // console.log(clientX, clientY);

        // 获取画布相较于窗口的位置
        const { left, top, width, height } = canvas.getBoundingClientRect();

        // 计算鼠标点击位置相较于画布位置
        const [cssX, cssY] = [clientX - left, clientY - top];

        // 获取画布的一半宽高
        const [halfWidth, halfHeight] = [width / 2, height / 2];

        // 将鼠标点击位置坐标映射到webgl坐标系中
        const [xBaseCenter, yBaseCenter] = [
          cssX - halfWidth,
          cssY - halfHeight,
        ];
        const [x, y] = [xBaseCenter / halfWidth, -yBaseCenter / halfHeight];
        const seed = Math.random();

        points.push({
          x,
          y,
          size: seed * 50 + 10,
          color: {
            r: seed,
            g: seed,
            b: 1,
          },
        });

        render();
      });

      function render() {
        gl.clear(gl.COLOR_BUFFER_BIT);
        points.forEach(({ x, y, size, color }) => {
          gl.vertexAttrib3f(point_Position, x, y, 0.0, 1.0);
          gl.vertexAttrib1f(point_Size, size);
          // gl.uniform4f(point_Color, color.r, color.g, color.b, 1);
          gl.uniform4fv(point_Color, [color.r, color.g, color.b, 1]);
          gl.drawArrays(gl.POINTS, 0, 1);
        });
      }

      // 使用着色器
      gl.useProgram(program);
      // 设置清屏颜色
      gl.clearColor(0, 0, 0, 1);
      // 清屏
      gl.clear(gl.COLOR_BUFFER_BIT);
    </script>
  </body>
</html>
